import {Component, ComponentProps, VueComponent, Link, Hook, Mut, Computed} from "vue3-oop";
import {DialogReactive, NButton, NButtonGroup, NScrollbar, NSpace} from "naive-ui";
import Codemirror from "codemirror-editor-vue3";
import 'codemirror/theme/monokai.css'
import 'codemirror/mode/javascript/javascript.js';
import 'codemirror/mode/xml/xml.js';
import { nicon } from "@/utils/IconUtil";
import BpmnModeler from '../BpmnModeler'

interface IProps {
  bpmnModeler: BpmnModeler
}
@Component()
export default class Index extends VueComponent<IProps> {
  static defaultProps: ComponentProps<IProps> = {
    bpmnModeler: {default:{} as any}
  }

  constructor() {
    super()
  }

  @Mut() private state = {
    scale:100,
    canUndo:false,
    canRedo:false,
  }

  // 预览BPMN的XML代码
  private handlePreviewBpmnXml=()=>{
    this.props.bpmnModeler.exportBpmnContent().then(({xml}:any)=>{
      const dialog = window.$popUp({
        style: {width:`${window.$size.width-200}px`,height:`${window.$size.height-200}px`,padding:"10px"},
        title: "BPMN预览",
        content:()=>(
          <NScrollbar style={{maxHeight:'740px'}} xScrollable={true}>
            <Codemirror
              value={xml}
              border
              options={{
                mode: 'xml', // 语言模式
                theme: 'darcula', // 主题
                lineNumbers: true, // 显示行号
                smartIndent: true, // 智能缩进
                readOnly: true,
                indentUnit: 2, // 智能缩进单位为4个空格长度
                foldGutter: true, // 启用行槽中的代码折叠
                styleActiveLine: true // 显示选中行的样式
              }}
            />
          </NScrollbar>
        )
      }) as DialogReactive;
    }).catch((err:any)=>{
      console.error(`[Process Designer Warn ]: ${err.message || err}`);
    })
  }

  // 缩小/放大/重置
  private handleCanvasZomm=(type:'OUT'|'IN'|'RESET')=>{
    if(type==='OUT'){
      let newScale = this.state.scale - 5;
      this.state.scale = newScale<20?20:newScale;
      this.props.bpmnModeler.zoomModelerCanvas(this.state.scale/100);
    }else if(type==='IN'){
      let newScale = this.state.scale + 5;
      this.state.scale = newScale>400?400:newScale;
      this.props.bpmnModeler.zoomModelerCanvas(this.state.scale/100);
    }else{
      this.state.scale = 100;
      this.props.bpmnModeler.zoomModelerCanvas('RESET');
    }
  }

  // 撤销/重做/重新加载
  private handleEditStep=(type:'UNDO'|'REDO'|'RELOAD')=>{
    if(type==='UNDO'){
      this.props.bpmnModeler.undo();
    }else if(type==='REDO'){
      this.props.bpmnModeler.redo();
    }else{
      this.props.bpmnModeler.importBpmnContent();
      this.state.canUndo = false;
      this.state.canRedo = false;
    }
  }

  @Hook("Mounted")
  private onMounted(){
    // 监听图形改变
    this.props.bpmnModeler.onCommandStackChanged((e:any)=>{
      this.state.canUndo = this.props.bpmnModeler.canUndo();
      this.state.canRedo = this.props.bpmnModeler.canRedo();
    })
    // 监听视图缩放变化
    this.props.bpmnModeler.onCanvasViewboxChanged( (e:any) => {
      // this.$emit("canvas-viewbox-changed", { viewbox });
      const scale = Math.round(e.viewbox.scale*100);
      if(this.state.scale!==scale){
        this.state.scale=scale
      }
    });
  }

  render(){
    return(
      <NSpace>
        <NButtonGroup size={"small"}>
          <NButton onClick={this.props.bpmnModeler.importBpmnFile}>导入文件</NButton>
          <NButton onClick={this.props.bpmnModeler.exportBpmnFile}>导出文件</NButton>
          <NButton onClick={this.handlePreviewBpmnXml}>预览</NButton>
          <NButton onClick={this.props.bpmnModeler.toggleSimulation}>模拟</NButton>
        </NButtonGroup>
        <NButtonGroup size={"small"}>
          <NButton onClick={()=>{this.props.bpmnModeler.alignSelectedElement('left')}}>{{icon:nicon("AlignHorizontalLeftRound")}}</NButton>
          <NButton onClick={()=>{this.props.bpmnModeler.alignSelectedElement('right')}}>{{icon:nicon("AlignHorizontalRightRound")}}</NButton>
          <NButton onClick={()=>{this.props.bpmnModeler.alignSelectedElement('top')}}>{{icon:nicon("AlignVerticalTopRound")}}</NButton>
          <NButton onClick={()=>{this.props.bpmnModeler.alignSelectedElement('bottom')}}>{{icon:nicon("AlignVerticalBottomRound")}}</NButton>
          <NButton onClick={()=>{this.props.bpmnModeler.alignSelectedElement('center')}}>{{icon:nicon("AlignHorizontalCenterRound")}}</NButton>
          <NButton onClick={()=>{this.props.bpmnModeler.alignSelectedElement('middle')}}>{{icon:nicon("AlignVerticalCenterRound")}}</NButton>
        </NButtonGroup>
        <NButtonGroup size={"small"}>
          <NButton onClick={()=>{this.handleCanvasZomm('OUT')}}>{{icon:nicon("ZoomOutOutlined")}}</NButton>
          <NButton onClick={()=>{this.handleCanvasZomm('RESET')}}>{`${this.state.scale}%`}</NButton>
          <NButton onClick={()=>{this.handleCanvasZomm('IN')}}>{{icon:nicon("ZoomInOutlined")}}</NButton>
        </NButtonGroup>
        <NButtonGroup size={"small"}>
          <NButton disabled={!this.state.canUndo} onClick={()=>{this.handleEditStep('UNDO')}}>{{icon:nicon("ArrowUndoSharp")}}</NButton>
          <NButton disabled={!this.state.canRedo} onClick={()=>{this.handleEditStep('REDO')}}>{{icon:nicon("ArrowRedoSharp")}}</NButton>
          <NButton onClick={()=>{this.handleEditStep('RELOAD')}}>{{icon:nicon("MdRefreshCircle")}}</NButton>
        </NButtonGroup>
      </NSpace>
    )
  }

}